package com.cooper.service.core;

import java.util.List;

import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.TriggerBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.cooper.dao.core.SchedulerDAO;
import com.cooper.entity.SchedulerInfo;

@Service
public class SchedulerService {
	
	private Logger logger = LoggerFactory.getLogger(this.getClass());
	
	public static final String DEFAULT_SCHEDULER_GROUP_NAME = "group1";
	
	@Autowired
	private SchedulerDAO schedulerDao;
	
	@Autowired
	private Scheduler scheduler = null;
	
	public List<SchedulerInfo> queryForList(){
		return this.schedulerDao.queryForList();
	}
	
	public SchedulerInfo loadById(Long id){
		return this.schedulerDao.loadById(id);
	}
	
	public SchedulerInfo getSchedulerByName(String jobName){
		return this.schedulerDao.getScheduler(jobName);
	}
	
	public Long addScheduler(SchedulerInfo sched, boolean bEffect) throws Exception{
		Long id = this.schedulerDao.addScheduler(sched);
		if(bEffect){
			this.addTask(sched);
		}
		return id;
	}
	
	public int updateScheduler(SchedulerInfo sched, boolean bEffect) throws Exception{
		int result = this.schedulerDao.updateScheduler(sched);
		if(bEffect){
			JobKey jobKey = new JobKey(sched.getJobName(), DEFAULT_SCHEDULER_GROUP_NAME);
			if(scheduler.checkExists(jobKey)){
				scheduler.deleteJob(jobKey);
			}
			this.addTask(sched);
		}
		return result;
	}
	
	public boolean deleteScheduler(SchedulerInfo sched, boolean bEffect) throws Exception{
		boolean result = this.schedulerDao.deleteScheduler(sched) > 0;
		if(bEffect){
			JobKey jobKey = new JobKey(sched.getJobName(), DEFAULT_SCHEDULER_GROUP_NAME);
			scheduler.deleteJob(jobKey);
		}
		return result;
	}
	
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public void addTask(SchedulerInfo sched) throws Exception{
		logger.info("Add schedule job {} for [{}]", sched.getJobName(), sched.getJobClass());
		// define the job and tie it to our HelloJob class
		Class jobClazz = Class.forName(sched.getJobClass());
		JobDetail jobDetail = JobBuilder.newJob(jobClazz)
				.withIdentity(sched.getJobName(), DEFAULT_SCHEDULER_GROUP_NAME).build();

		// Trigger the job to run now, and then repeat every 40 seconds
		CronTrigger trigger = TriggerBuilder.newTrigger()
	        .withIdentity(sched.getJobName(), DEFAULT_SCHEDULER_GROUP_NAME)
	        .withSchedule(CronScheduleBuilder.cronSchedule(sched.getCronText()))
	        .build();
		
		scheduler.scheduleJob(jobDetail, trigger);
	}
	
	public void executeTask(SchedulerInfo sched) throws Exception{
		logger.info("Manual trigger schedule job {} for [{}]", sched.getJobName(), sched.getJobClass());
		JobKey jobKey = new JobKey(sched.getJobName(), DEFAULT_SCHEDULER_GROUP_NAME);
		scheduler.triggerJob(jobKey);
	}
	
	public void refreshAllTask() throws Exception{
		scheduler.standby();
		List<SchedulerInfo> schedulerList = this.queryForList();
		if(null != schedulerList){
			for(SchedulerInfo sched: schedulerList){
				JobKey jobKey = new JobKey(sched.getJobName(), DEFAULT_SCHEDULER_GROUP_NAME);
				if(scheduler.checkExists(jobKey)){
					
				} else {
					this.addTask(sched);
				}
			}
			scheduler.start();
		}
	}
	
}
